#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt5.QtWidgets import (QMainWindow, QTabWidget, QWidget, QVBoxLayout, 
                            QHBoxLayout, QAction, QToolBar, QComboBox, 
                            QLineEdit, QPushButton, QFileDialog, QMessageBox,
                            QLabel, QStatusBar, QMenu, QSplitter, QDialog, 
                            QTableWidget, QTableWidgetItem, QHeaderView, QAbstractItemView, QApplication)
from PyQt5.QtCore import Qt, pyqtSignal, QSize
from PyQt5.QtGui import QIcon, QPixmap

from ui.packet_list_widget import PacketListWidget
from ui.packet_detail_widget import PacketDetailWidget
from ui.statistics_widget import StatisticsWidget
from ui.filter_widget import FilterWidget

class InterfaceSelectionDialog(QDialog):
    """
    网络接口选择对话框，类似Wireshark的接口选择界面
    """
    
    def __init__(self, parent=None, interfaces=None):
        """
        初始化接口选择对话框
        
        Args:
            parent: 父窗口
            interfaces: 网络接口列表
        """
        super().__init__(parent)
        self.interfaces = interfaces or []
        self.selected_interface = None
        self._setup_ui()
        
    def _setup_ui(self):
        """
        设置UI组件
        """
        self.setWindowTitle("捕获接口选择")
        self.setMinimumSize(800, 500)
        
        # 创建主布局
        layout = QVBoxLayout(self)
        
        # 创建说明标签
        info_label = QLabel("选择要捕获的网络接口：")
        info_label.setStyleSheet("font-weight: bold; margin-bottom: 10px;")
        layout.addWidget(info_label)
        
        # 创建接口表格
        self.interface_table = QTableWidget(0, 7)
        self.interface_table.setHorizontalHeaderLabels(["接口名称", "类型", "描述", "IP地址", "IPv6地址", "MAC地址", "状态"])
        
        # 设置列宽
        self.interface_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self.interface_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeToContents)
        self.interface_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)
        self.interface_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeToContents)
        self.interface_table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeToContents)
        self.interface_table.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeToContents)
        self.interface_table.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeToContents)
        
        self.interface_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.interface_table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.interface_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.interface_table.itemDoubleClicked.connect(self._on_interface_double_clicked)
        self.interface_table.setAlternatingRowColors(True)
        self.interface_table.setStyleSheet("""
            QTableWidget {
                gridline-color: #d0d0d0;
                background-color: white;
                alternate-background-color: #f6f6f6;
            }
            QTableWidget::item:selected {
                background-color: #0078d7;
                color: white;
            }
        """)
        
        # 填充接口数据
        self._fill_interface_table()
        
        layout.addWidget(self.interface_table)
        
        # 添加帮助说明文本
        help_text = QLabel("双击接口或选中后点击\"选择\"按钮开始捕获。回环接口(127.0.0.1)用于捕获本地通信。")
        help_text.setWordWrap(True)
        help_text.setStyleSheet("color: #666; font-size: 11px; margin-top: 5px;")
        layout.addWidget(help_text)
        
        # 创建按钮布局
        button_layout = QHBoxLayout()
        
        # 刷新按钮
        refresh_button = QPushButton("刷新")
        refresh_button.setIcon(QIcon.fromTheme("view-refresh"))
        refresh_button.clicked.connect(self._on_refresh_clicked)
        button_layout.addWidget(refresh_button)
        
        # 添加空白区域
        button_layout.addStretch()
        
        # 选择按钮
        select_button = QPushButton("选择")
        select_button.setDefault(True)
        select_button.clicked.connect(self._on_select_clicked)
        button_layout.addWidget(select_button)
        
        # 取消按钮
        cancel_button = QPushButton("取消")
        cancel_button.clicked.connect(self.reject)
        button_layout.addWidget(cancel_button)
        
        layout.addLayout(button_layout)
        
        self.setLayout(layout)
        
    def _fill_interface_table(self):
        """
        填充接口表格数据
        """
        self.interface_table.setRowCount(0)
        
        for i, iface in enumerate(self.interfaces):
            self.interface_table.insertRow(i)
            
            # 接口名称
            name_item = QTableWidgetItem(iface.get('name', 'Unknown'))
            self.interface_table.setItem(i, 0, name_item)
            
            # 接口类型
            iface_type = iface.get('type', '未知')
            type_item = QTableWidgetItem(iface_type)
            self.interface_table.setItem(i, 1, type_item)
            
            # 根据接口类型设置图标
            if iface_type == '以太网':
                type_item.setIcon(QIcon.fromTheme("network-wired"))
            elif iface_type == '无线':
                type_item.setIcon(QIcon.fromTheme("network-wireless"))
            elif iface_type == '回环':
                type_item.setIcon(QIcon.fromTheme("network-loopback"))
            elif iface_type == '虚拟':
                type_item.setIcon(QIcon.fromTheme("network-vpn"))
            
            # 接口描述
            desc_item = QTableWidgetItem(iface.get('description', 'No description'))
            self.interface_table.setItem(i, 2, desc_item)
            
            # IP地址
            addresses = iface.get('addresses', [])
            addr_text = ", ".join(addresses) if addresses else "无"
            addr_item = QTableWidgetItem(addr_text)
            self.interface_table.setItem(i, 3, addr_item)
            
            # IPv6地址
            ipv6_addresses = iface.get('ipv6_addresses', [])
            ipv6_text = ipv6_addresses[0] if ipv6_addresses else "无"
            if len(ipv6_addresses) > 1:
                ipv6_text += f" (+{len(ipv6_addresses)-1})"
            ipv6_item = QTableWidgetItem(ipv6_text)
            self.interface_table.setItem(i, 4, ipv6_item)
            
            # MAC地址
            mac_item = QTableWidgetItem(iface.get('mac_address', '无'))
            self.interface_table.setItem(i, 5, mac_item)
            
            # 状态
            status_text = iface.get('status', '未知')
            status_item = QTableWidgetItem(status_text)
            status_item.setTextAlignment(Qt.AlignCenter)
            
            # 设置状态颜色
            if status_text == '已连接':
                status_item.setForeground(Qt.darkGreen)
                status_item.setIcon(QIcon.fromTheme("network-transmit-receive"))
            elif status_text == '未连接':
                status_item.setForeground(Qt.darkRed)
                status_item.setIcon(QIcon.fromTheme("network-offline"))
                
            self.interface_table.setItem(i, 6, status_item)
            
        # 如果有接口，默认选择第一个
        if self.interface_table.rowCount() > 0:
            self.interface_table.selectRow(0)
            
        # 调整行高
        for i in range(self.interface_table.rowCount()):
            self.interface_table.setRowHeight(i, 30)
            
    def _on_refresh_clicked(self):
        """
        处理刷新按钮点击
        """
        # 请求父窗口刷新接口列表
        if self.parent() and hasattr(self.parent(), "app_controller"):
            self.parent().app_controller._init_interfaces()
            self.interfaces = self.parent().app_controller.capturer.get_interfaces()
            self._fill_interface_table()
            
    def _on_select_clicked(self):
        """
        处理选择按钮点击
        """
        selected_rows = self.interface_table.selectedIndexes()
        if selected_rows:
            row = selected_rows[0].row()
            if 0 <= row < len(self.interfaces):
                self.selected_interface = self.interfaces[row]
                self.accept()
        else:
            QMessageBox.warning(self, "选择错误", "请选择一个网络接口")
            
    def _on_interface_double_clicked(self, item):
        """
        处理接口双击事件
        """
        row = item.row()
        if 0 <= row < len(self.interfaces):
            self.selected_interface = self.interfaces[row]
            self.accept()
            
    def get_selected_interface(self):
        """
        获取选择的接口
        
        Returns:
            dict: 选择的接口信息
        """
        return self.selected_interface

class MainWindow(QMainWindow):
    """
    主窗口类，程序的主界面
    """
    
    def __init__(self, app_controller=None):
        """
        初始化主窗口
        
        Args:
            app_controller: 应用控制器对象，用于连接GUI和核心功能
        """
        super().__init__()
        self.app_controller = app_controller
        
        # 设置窗口属性
        self.setWindowTitle("网络数据包分析工具")
        self.setMinimumSize(1024, 768)
        
        # 创建UI组件
        self._create_actions()
        self._create_menus()
        self._create_toolbars()
        self._create_status_bar()
        self._create_central_widget()
        
        # 显示欢迎信息
        self.statusBar().showMessage("就绪")
        
    def _create_actions(self):
        """
        创建菜单和工具栏操作
        """
        # 文件菜单操作
        self.start_action = QAction(QIcon.fromTheme("media-playback-start"), "开始捕获", self)
        self.start_action.setShortcut("Ctrl+E")
        self.start_action.setStatusTip("开始捕获数据包")
        self.start_action.triggered.connect(self._on_start_capture)
        
        self.stop_action = QAction(QIcon.fromTheme("media-playback-stop"), "停止捕获", self)
        self.stop_action.setShortcut("Ctrl+S")
        self.stop_action.setStatusTip("停止捕获数据包")
        self.stop_action.setEnabled(False)  # 初始状态下禁用
        self.stop_action.triggered.connect(self._on_stop_capture)
        
        self.open_action = QAction(QIcon.fromTheme("document-open"), "打开", self)
        self.open_action.setShortcut("Ctrl+O")
        self.open_action.setStatusTip("打开捕获文件")
        self.open_action.triggered.connect(self._on_open_file)
        
        self.save_action = QAction(QIcon.fromTheme("document-save"), "保存", self)
        self.save_action.setShortcut("Ctrl+S")
        self.save_action.setStatusTip("保存捕获文件")
        self.save_action.triggered.connect(self._on_save_capture)
        
        self.export_action = QAction(QIcon.fromTheme("document-export"), "导出", self)
        self.export_action.setStatusTip("导出捕获结果")
        self.export_action.triggered.connect(self._on_export_results)
        
        self.exit_action = QAction(QIcon.fromTheme("application-exit"), "退出", self)
        self.exit_action.setShortcut("Ctrl+Q")
        self.exit_action.setStatusTip("退出应用程序")
        self.exit_action.triggered.connect(self.close)
        
        # 视图菜单操作
        self.toggle_toolbar_action = QAction("显示工具栏", self)
        self.toggle_toolbar_action.setStatusTip("切换工具栏显示")
        self.toggle_toolbar_action.setCheckable(True)
        self.toggle_toolbar_action.setChecked(True)
        self.toggle_toolbar_action.triggered.connect(self._on_toggle_toolbar)
        
        self.toggle_statusbar_action = QAction("显示状态栏", self)
        self.toggle_statusbar_action.setStatusTip("切换状态栏显示")
        self.toggle_statusbar_action.setCheckable(True)
        self.toggle_statusbar_action.setChecked(True)
        self.toggle_statusbar_action.triggered.connect(self._on_toggle_statusbar)
        
        # 捕获菜单操作
        self.port_scan_detection_action = QAction("启用端口扫描检测", self)
        self.port_scan_detection_action.setStatusTip("检测可能的端口扫描行为")
        self.port_scan_detection_action.setCheckable(True)
        self.port_scan_detection_action.setChecked(False)
        self.port_scan_detection_action.triggered.connect(self._on_toggle_port_scan_detection)
        
        # 帮助菜单操作
        self.about_action = QAction("关于", self)
        self.about_action.setStatusTip("显示关于信息")
        self.about_action.triggered.connect(self._on_about)
        
    def _create_menus(self):
        """
        创建菜单栏
        """
        menubar = self.menuBar()
        
        # 文件菜单
        file_menu = menubar.addMenu("文件")
        file_menu.addAction(self.start_action)
        file_menu.addAction(self.stop_action)
        file_menu.addSeparator()
        file_menu.addAction(self.open_action)
        file_menu.addAction(self.save_action)
        file_menu.addAction(self.export_action)
        file_menu.addSeparator()
        file_menu.addAction(self.exit_action)
        
        # 编辑菜单
        edit_menu = menubar.addMenu("编辑")
        # TODO: 添加编辑相关菜单项
        
        # 视图菜单
        view_menu = menubar.addMenu("视图")
        view_menu.addAction(self.toggle_toolbar_action)
        view_menu.addAction(self.toggle_statusbar_action)
        
        # 捕获菜单
        capture_menu = menubar.addMenu("捕获")
        capture_menu.addAction(self.port_scan_detection_action)
        # TODO: 添加更多捕获相关菜单项
        
        # 统计菜单
        statistics_menu = menubar.addMenu("统计")
        # TODO: 添加统计相关菜单项
        
        # 帮助菜单
        help_menu = menubar.addMenu("帮助")
        help_menu.addAction(self.about_action)
        
    def _create_toolbars(self):
        """
        创建工具栏
        """
        self.main_toolbar = QToolBar("主工具栏")
        self.addToolBar(self.main_toolbar)
        
        # 添加接口选择下拉框和标签
        interface_label = QLabel("接口: ")
        self.main_toolbar.addWidget(interface_label)
        
        self.interface_combo = QComboBox()
        self.interface_combo.setMinimumWidth(350)
        self.interface_combo.setToolTip("选择要捕获的网络接口")
        self.main_toolbar.addWidget(self.interface_combo)
        
        # 添加接口选择按钮
        interface_button = QPushButton("选择...")
        interface_button.setToolTip("打开接口选择对话框")
        interface_button.clicked.connect(self._show_interface_dialog)
        self.main_toolbar.addWidget(interface_button)
        
        self.main_toolbar.addSeparator()
        
        # 添加过滤器标签和输入框
        filter_label = QLabel("捕获过滤器: ")
        self.main_toolbar.addWidget(filter_label)
        
        self.filter_edit = QLineEdit()
        self.filter_edit.setPlaceholderText("输入BPF过滤表达式 (如: tcp port 80)")
        self.filter_edit.setMinimumWidth(200)
        self.filter_edit.setToolTip("输入BPF过滤表达式，例如 'tcp port 80' 或 'host 192.168.1.1'")
        self.main_toolbar.addWidget(self.filter_edit)
        
        self.main_toolbar.addSeparator()
        
        # 添加捕获控制按钮
        self.main_toolbar.addAction(self.start_action)
        self.main_toolbar.addAction(self.stop_action)
        self.main_toolbar.addSeparator()
        self.main_toolbar.addAction(self.open_action)
        self.main_toolbar.addAction(self.save_action)
        
        # 刷新接口列表
        self._refresh_interfaces()
        
    def _create_status_bar(self):
        """
        创建状态栏
        """
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        
        # 添加状态指示器
        self.packet_count_label = QLabel("捕获: 0 个数据包")
        self.status_bar.addPermanentWidget(self.packet_count_label)
        
        self.status_label = QLabel("就绪")
        self.status_bar.addWidget(self.status_label)
        
    def _create_central_widget(self):
        """
        创建中央窗口部件
        """
        # 创建中央窗口部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(2, 2, 2, 2)
        main_layout.setSpacing(2)
        
        # 创建过滤器部件
        self.filter_widget = FilterWidget()
        self.filter_widget.filter_applied.connect(self._on_filter_applied)
        main_layout.addWidget(self.filter_widget)
        
        # 创建拆分器
        splitter = QSplitter(Qt.Vertical)
        splitter.setChildrenCollapsible(False)
        main_layout.addWidget(splitter, 1)
        
        # 创建数据包列表部件
        self.packet_list_widget = PacketListWidget()
        self.packet_list_widget.packet_selected.connect(self._on_packet_selected)
        splitter.addWidget(self.packet_list_widget)
        
        # 创建详细信息部件
        self.detail_widget = PacketDetailWidget()
        splitter.addWidget(self.detail_widget)
        
        # 设置拆分器初始大小
        splitter.setSizes([300, 200])
        
        # 创建统计信息标签页
        self.tab_widget = QTabWidget()
        self.tab_widget.setTabPosition(QTabWidget.South)
        
        # 创建统计部件
        self.statistics_widget = StatisticsWidget()
        self.tab_widget.addTab(self.statistics_widget, "统计")
        
        # 添加到主布局
        main_layout.addWidget(self.tab_widget)
        
        # 创建状态栏信息
        status_layout = QHBoxLayout()
        status_layout.setContentsMargins(5, 0, 5, 0)
        
        # 数据包计数标签
        self.packet_count_label = QLabel("捕获: 0 个数据包")
        status_layout.addWidget(self.packet_count_label)
        
        # 添加空白间隔
        status_layout.addStretch()
        
        # 添加状态栏信息到主布局
        main_layout.addLayout(status_layout)
        
    def _refresh_interfaces(self):
        """
        刷新网络接口列表
        """
        if self.app_controller:
            self.app_controller._init_interfaces()
            self.statusBar().showMessage("网络接口列表已刷新", 3000)
            
    def _on_start_capture(self):
        """
        处理开始捕获按钮点击
        """
        if self.app_controller:
            # 获取选择的接口对象
            selected_interface = self.interface_combo.currentData()
            filter_text = self.filter_edit.text()
            
            success = self.app_controller.start_capture(selected_interface, filter_text)
            if success:
                self.start_action.setEnabled(False)
                self.stop_action.setEnabled(True)
                self.status_label.setText("正在捕获...")
            else:
                QMessageBox.warning(self, "捕获错误", "无法开始捕获，请检查网络接口和过滤器设置。")
        
    def _on_stop_capture(self):
        """
        处理停止捕获按钮点击
        """
        if self.app_controller:
            self.app_controller.stop_capture()
            self.start_action.setEnabled(True)
            self.stop_action.setEnabled(False)
            self.status_label.setText("捕获已停止")
        
    def _on_open_file(self):
        """
        处理打开文件按钮点击
        """
        if self.app_controller:
            file_path, _ = QFileDialog.getOpenFileName(
                self, 
                "打开捕获文件", 
                "", 
                "捕获文件 (*.pcap *.pcapng);;所有文件 (*.*)"
            )
            
            if file_path:
                success = self.app_controller.load_capture_file(file_path)
                if not success:
                    QMessageBox.warning(self, "打开文件错误", "无法打开选定的文件。")
        
    def _on_save_capture(self):
        """
        处理保存捕获按钮点击
        """
        if self.app_controller:
            file_path, _ = QFileDialog.getSaveFileName(
                self, 
                "保存捕获文件", 
                "", 
                "捕获文件 (*.pcap *.pcapng);;所有文件 (*.*)"
            )
            
            if file_path:
                success = self.app_controller.save_capture_file(file_path)
                if success:
                    self.statusBar().showMessage(f"捕获已保存到 {file_path}", 3000)
                else:
                    QMessageBox.warning(self, "保存文件错误", "无法保存捕获文件。")
        
    def _on_export_results(self):
        """
        处理导出结果按钮点击
        """
        if self.app_controller:
            export_menu = QMenu(self)
            export_json_action = QAction("导出为JSON", self)
            export_csv_action = QAction("导出为CSV", self)
            
            export_menu.addAction(export_json_action)
            export_menu.addAction(export_csv_action)
            
            export_json_action.triggered.connect(self._export_as_json)
            export_csv_action.triggered.connect(self._export_as_csv)
            
            # 显示导出菜单
            pos = self.mapToGlobal(self.export_action.parentWidget().pos())
            export_menu.exec_(pos)
        
    def _export_as_json(self):
        """
        导出为JSON格式
        """
        if self.app_controller:
            file_path, _ = QFileDialog.getSaveFileName(
                self, 
                "导出为JSON", 
                "", 
                "JSON文件 (*.json);;所有文件 (*.*)"
            )
            
            if file_path:
                success = self.app_controller.export_as_json(file_path)
                if success:
                    self.statusBar().showMessage(f"已导出到 {file_path}", 3000)
                else:
                    QMessageBox.warning(self, "导出错误", "无法导出为JSON格式。")
        
    def _export_as_csv(self):
        """
        导出为CSV格式
        """
        if self.app_controller:
            file_path, _ = QFileDialog.getSaveFileName(
                self, 
                "导出为CSV", 
                "", 
                "CSV文件 (*.csv);;所有文件 (*.*)"
            )
            
            if file_path:
                success = self.app_controller.export_as_csv(file_path)
                if success:
                    self.statusBar().showMessage(f"已导出到 {file_path}", 3000)
                else:
                    QMessageBox.warning(self, "导出错误", "无法导出为CSV格式。")
        
    def _on_toggle_toolbar(self, checked):
        """
        切换工具栏显示状态
        """
        self.main_toolbar.setVisible(checked)
        
    def _on_toggle_statusbar(self, checked):
        """
        切换状态栏显示状态
        """
        self.statusBar().setVisible(checked)
        
    def _on_toggle_port_scan_detection(self, checked):
        """
        切换端口扫描检测功能
        """
        if self.app_controller:
            self.app_controller.set_port_scan_detection(checked)
            status = "启用" if checked else "禁用"
            self.statusBar().showMessage(f"端口扫描检测已{status}", 3000)
        
    def _on_about(self):
        """
        显示关于对话框
        """
        QMessageBox.about(
            self,
            "关于网络数据包分析工具",
            "网络数据包分析工具 v1.0\n\n"
            "一个基于PyQt5和Scapy/PyShark的网络数据包分析工具，\n"
            "能够捕获、解析、展示网络数据包，并提供基本的统计分析功能。\n\n"
            "计网实验大作业付航32301081"
        )
        
    def _on_packet_selected(self, packet_index):
        """
        处理数据包选择事件
        """
        if self.app_controller:
            packet = self.app_controller.get_packet_at_index(packet_index)
            if packet:
                self.detail_widget.display_packet(packet)
                
    def _on_filter_applied(self, filter_text):
        """
        处理过滤器应用事件
        """
        if self.app_controller:
            self.app_controller.apply_display_filter(filter_text)
            
    def update_interface_list(self, interfaces):
        """
        更新网络接口下拉列表
        
        Args:
            interfaces: 网络接口列表，包含接口详细信息的字典列表
        """
        self.interface_combo.clear()
        
        # 如果接口列表为空，添加一个默认项
        if not interfaces:
            self.interface_combo.addItem("无可用接口")
            return
            
        # 按类型和名称排序接口
        def sort_key(iface):
            # 按接口类型和名称排序，以太网和无线优先
            type_order = {'以太网': 0, '无线': 1, '回环': 2, '虚拟': 3, '其他': 4}
            iface_type = iface.get('type', '其他')
            return (type_order.get(iface_type, 5), iface.get('name', ''))
            
        sorted_interfaces = sorted(interfaces, key=sort_key)
        
        # 为每个接口创建显示文本
        for i, iface in enumerate(sorted_interfaces):
            name = iface.get('name', 'Unknown')
            desc = iface.get('description', '')
            addresses = iface.get('addresses', [])
            iface_type = iface.get('type', '未知')
            status = iface.get('status', '未知')
            
            # 创建显示文本
            display_text = name
            if iface_type:
                display_text = f"[{iface_type}] {display_text}"
                
            if desc:
                # 截断过长的描述
                if len(desc) > 40:
                    desc = desc[:37] + "..."
                display_text += f" - {desc}"
                
            # 简短地显示IP地址
            if addresses:
                display_text += f" ({addresses[0]})"
                
            # 显示状态
            if status == '已连接':
                display_text += " ✓"
            elif status == '未连接':
                display_text += " ✗"
                
            # 添加到下拉菜单并存储完整接口对象
            self.interface_combo.addItem(display_text)
            self.interface_combo.setItemData(i, iface)
            
    def _show_interface_dialog(self):
        """
        显示接口选择对话框
        """
        if self.app_controller:
            # 获取最新的接口列表
            interfaces = self.app_controller.capturer.get_interfaces()
            
            # 创建并显示对话框
            dialog = InterfaceSelectionDialog(self, interfaces)
            result = dialog.exec_()
            
            if result == QDialog.Accepted:
                selected_interface = dialog.get_selected_interface()
                if selected_interface:
                    # 更新接口下拉框选择
                    for i in range(self.interface_combo.count()):
                        iface = self.interface_combo.itemData(i)
                        if iface and iface.get('name') == selected_interface.get('name'):
                            self.interface_combo.setCurrentIndex(i)
                            break
                    
                    # 显示所选接口的基本信息
                    name = selected_interface.get('name', 'Unknown')
                    iface_type = selected_interface.get('type', '')
                    addresses = selected_interface.get('addresses', [])
                    ip_str = ", ".join(addresses) if addresses else "无IP地址"
                    
                    self.statusBar().showMessage(f"已选择接口: {name} [{iface_type}] {ip_str}", 5000)
        
    def update_packet_list(self, packets):
        """
        更新数据包列表
        
        Args:
            packets: 解析后的数据包列表
        """
        try:
            # 使用QApplication.processEvents()让UI保持响应
            QApplication.processEvents()
            
            # 更新数据包列表
            self.packet_list_widget.update_packets(packets)
            
            # 更新状态栏
            self.statusBar().showMessage(f"显示 {len(packets)} 个数据包")
        except Exception as e:
            self.display_error(f"更新数据包列表时出错: {str(e)}", show_popup=False)
        
    def display_error(self, error_message, show_popup=True):
        """
        显示错误消息
        
        Args:
            error_message: 错误消息
            show_popup: 是否弹出对话框，默认为True
        """
        try:
            # 如果是状态更新消息且不需要弹窗，只更新状态栏
            if not show_popup:
                self.statusBar().showMessage(error_message)
                return
                
            # 打印到控制台
            print(f"错误: {error_message}")
            
            # 更新状态栏
            self.statusBar().showMessage(f"错误: {error_message}")
            
            # 显示对话框
            QMessageBox.warning(self, "错误", error_message)
        except Exception as e:
            # 确保任何错误都不会阻止程序继续运行
            print(f"显示错误消息时发生异常: {str(e)}")
            print(f"原始错误消息: {error_message}")
            
    def closeEvent(self, event):
        """
        窗口关闭事件处理
        
        Args:
            event: 关闭事件对象
        """
        try:
            # 如果正在捕获，停止捕获
            if self.app_controller and hasattr(self.app_controller.capturer, 'is_capturing') and self.app_controller.capturer.is_capturing:
                self.app_controller.stop_capture()
                
            # 清理资源
            if self.app_controller:
                # 确保释放资源
                if hasattr(self.app_controller, 'capturer'):
                    if hasattr(self.app_controller.capturer, 'stop_capture'):
                        self.app_controller.capturer.stop_capture()
                
                # 停止定时器
                if hasattr(self.app_controller, 'stats_timer') and self.app_controller.stats_timer.isActive():
                    self.app_controller.stats_timer.stop()
                    
            # 接受关闭事件
            event.accept()
        except Exception as e:
            print(f"应用关闭时出错: {str(e)}")
            event.accept()  # 确保窗口能关闭 

    def update_statistics(self, stats_data):
        """
        更新统计信息
        
        Args:
            stats_data: 统计数据字典
        """
        try:
            self.statistics_widget.update_statistics(stats_data)
        except Exception as e:
            print(f"更新统计信息时出错: {str(e)}")
            
    def display_alert(self, alert_message):
        """
        显示警报消息
        
        Args:
            alert_message: 警报消息文本
        """
        try:
            # 打印到控制台
            print(f"警报: {alert_message}")
            
            # 更新状态栏
            self.statusBar().showMessage(f"警报: {alert_message}")
            
            # 显示对话框
            QMessageBox.warning(self, "警报", alert_message)
        except Exception as e:
            print(f"显示警报时出错: {str(e)}")
            print(f"原始警报: {alert_message}") 